﻿namespace JoinBox.Basal;

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

/// <summary>
/// 转换大小写
/// </summary>
public enum ConvertCaseModes
{
    Unchanged,// 不改变,循环时候用
    ToUpper,
    ToLower,
}

public static partial class StringHelper
{
    /// <summary>
    /// 转换大小写
    /// </summary>
    /// <param name="name">字符串</param>
    /// <param name="convertCaseModes">转换模式</param>
    /// <returns>转换后的字符串</returns>
    public static string ConvertCase(this string name, ConvertCaseModes convertCaseModes)
    {
        switch (convertCaseModes)
        {
            case ConvertCaseModes.ToUpper:
                name = name.ToUpper();
                break;
            case ConvertCaseModes.ToLower:
                name = name.ToLower();
                break;
        }
        return name;
    }

    /// <summary>
    /// 是中文且有下划线
    /// </summary>
    /// <param name="str"></param>
    /// <returns></returns>
    public static bool IsChineseUnderline(this string str)
    {
        return Regex.Match(str, @"^[\u4e00-\u9fa5-_.]+$").Success;
    }
    /// <summary>
    /// 是英文且有下划线
    /// </summary>
    /// <param name="str"></param>
    /// <returns></returns>
    public static bool IsEnglistUnderline(this string str)
    {
        return Regex.Match(str, @"^[A-Za-z-_.]+$").Success;
    }
    /// <summary>
    /// 从头到尾是中文
    /// </summary>
    /// <param name="str"></param>
    /// <returns></returns>
    public static bool IsChineseAll(this string str)
    {
        return Regex.Match(str, @"^[\u4e00-\u9fa5]+$").Success;
    }
    /// <summary>
    /// 从头到尾是英文
    /// </summary>
    /// <param name="str"></param>
    /// <returns></returns>
    public static bool IsEnglistAll(this string str)
    {
        return Regex.Match(str, @"^[A-Za-z]+$").Success;
    }
    /// <summary>
    /// 翻转字符串
    /// </summary>
    /// <param name="str"></param>
    /// <returns></returns>
    public static string ReverseToString(this string str)
    {
        return new string(str.Reverse().ToArray());
    }

    /// <summary>
    /// 获取括号中间的字符串
    /// </summary>
    /// <param name="str">字符串</param>
    /// <returns></returns>
    // https://blog.csdn.net/wqsVSwcx/article/details/79805285
    public static List<string> GetInside(this string str)
    {
        string pattern = @"\(.*?\)";// 匹配模式
        var regex = new Regex(pattern, RegexOptions.IgnoreCase);
        var matches = regex.Matches(str);
        var sb = new List<string>();
        foreach (Match match in matches)
        {
            string value = match.Value.Trim('(', ')');
            sb.Add(value);
        }
        return sb;
    }


    /// <summary>
    /// 获取时间名
    /// </summary>
    /// <param name="miao">传出秒</param>
    /// <returns>返回一个不含秒的时间字符串</returns>
    public static string GetTimeNoSeconds(out int miao)
    {
        DateTime currentTime = DateTime.Now;
        miao = currentTime.Second;
        var now = currentTime.ToString("yyyyMMddHHmm"); // 年月日时分 yyyyMMddHHmmssfff
        return now;
    }
    /// <summary>
    /// 时间名
    /// </summary>
    /// <param name="time">输入一个不含秒的时间</param>
    /// <param name="miao">输入秒</param>
    /// <param name="a">秒数累加值</param>
    /// <returns>时间名</returns>
    public static string GetTimeName(string time, int miao)
    {
        return time + miao.ToString("#00");
    }
    /// <summary>
    /// 切割每个字成为数组,然后我发现字符串是可以遍历的..
    /// </summary>
    /// <param name="str"></param>
    /// <returns>string数组</returns>
    public static IEnumerable<string> Split(string str)
    {
        // 切割每个字符串,然后判断前面4位都要是数字(年份),然后设定项目日期.
        string[] rs = Regex.Split(str, @"()");
        // 使用lambda表达式过滤掉空字符串
        return rs.Where(s => !string.IsNullOrEmpty(s));// 清理空数组
    }
    /// <summary>
    /// 获取文件夹名字所有的数字
    /// </summary>
    /// <param name="project">项目文件夹名称</param>
    /// <returns>成功返回年份,失败返回0</returns>
    public static string GetFlie4Number(string project)
    {
        // 备份年份设定
        // 切割每个字符串,然后判断前面4位都要是数字(年份),然后设定项目日期.
        var beifennian = new StringBuilder();
        for (int i = 0; i < project.Length; i++)
            if (char.IsNumber(project[i]))// 判断是不是数字
                beifennian.Append(project[i]);

        string result = "0";
        if (beifennian.Length >= 4)
            result = beifennian.ToString(0, 4);
        return result;
    }
    /// <summary>
    /// 判断文本是否全是字母组合
    /// </summary>
    /// <param name="text">需判断的文本或是字符串</param>
    /// <returns>有字母存在返回<see langword="true"/></returns>
    // public static bool IsAllChar(this string text)
    // {
    //    foreach (char tempchar in text.ToCharArray())
    //        if (tempchar.IsAllChar() == false)
    //            return false;
    //    return true;
    // }
    /// <summary>
    /// 是字母
    /// </summary>
    /// <param name="tempchar">Char</param>
    /// <returns>有字母存在返回<see langword="true"/></returns>
    // public static bool IsAllChar(this char tempchar)
    // {
    //    // 是[字母范围](但是识别了中文) 和 非[中文范围]
    //    return (char.IsLetter(tempchar) && !(tempchar >= 19968 && tempchar <= 171941))
    // }
    /// <summary>
    /// 判断是否是数字
    /// </summary>
    /// <param name="str">字符串</param>
    /// <returns>bool</returns>
    // public static bool IsNumeric(this char tempchar)
    // {
    //    var ascii = new ASCIIEncoding();
    //    byte[] bytestr = ascii.GetBytes(new char[] { tempchar });
    //    foreach (byte c in bytestr)
    //        if (c < 48 || c > 57)
    //            return false;
    //    return true;
    // }
    /// <summary>
    /// 用 ASCII 码范围判断字符是不是汉字,含数字和字母和汉字
    /// </summary>
    /// <param name="text">待判断字符或字符串</param>
    /// <returns>真：是汉字；假：不是</returns>
    public static bool IsCheckStringChinese(this char tempchar)
    {
        bool res = false;
        if (tempchar > 127)
            res = true;
        return res;
    }
    /// <summary>
    /// 获取上级目录
    /// </summary>
    /// <param name="path">路径</param>
    /// <returns></returns>
    public static string PathHigherLevel(string path)
    {
        string str = PathInsertSlash(path, 1, false);
        int i1 = str.LastIndexOf("\\");// 获取字符串最后一个斜杠的位置

        // 取当前目录的字符串第一个字符到最后一个斜杠所在位置,相当于上级目录
        // str = path[..i1];
        str = path.Substring(0, i1);
        return str;
    }

#if true
    /// <summary>
    /// 在路径中间插入\
    /// </summary>
    /// <param name="path">路径</param>
    /// <param name="ints">中间\的数量</param>
    /// <param name="flag">true要末尾\,false不要末尾\</param>
    /// <returns></returns>
    public static string PathInsertSlash(string path, int ints, bool flag)
    {
        string x1 = string.Empty;
        for (int i = 0; i < ints; i++)
            x1 += '\\';
        var sArray = path.Split('\\');// 切割路径
        var list = sArray.ToList();   // 把数组转换成泛型类
        while (true)                  // 无论是否需要结尾的\,都先去掉
        {
            // if (list[^1] != string.Empty)
            if (list.Last() != string.Empty)
                break;
            list.RemoveAt(list.Count - 1);
        }
        string x = string.Empty;
        for (int i = 0; i < list.Count; i++)
        {
            if (list[i] != string.Empty)
            {
                x += list[i];
                if (i < list.Count - 1)
                    x += x1;
            }
        }
        if (flag) // 判断结尾是否有\
            x += x1;

        if (x == string.Empty)
            x = path;
        return x;
    }
#endif

    /// <summary>
    /// 排序:A1,A10,A2而我要的是A1,A2,A10
    /// </summary>
    /// <param name="strs"></param>
    /// <returns></returns>
    public static string[] StrSort(string[] strs)
    {
        CustomComparerFlag ??= new CustomComparer();
        Array.Sort(strs, CustomComparerFlag);
        return strs;
    }

    static CustomComparer? CustomComparerFlag;

    // https://www.cnblogs.com/xiaofengfeng/archive/2012/04/10/2441510.html
    class CustomComparer : IComparer
    {
        public int Compare(object? x, object? y)
        {
            if (x is null && y is null)
                return 0;

            var s1 = (string)x!;
            var s2 = (string)y!;
            int num = Math.Min(s1.Length, s2.Length); // 防止数组越过
            for (int i = 0; i < num; i++)
            {
                if (s1[i] > s2[i])
                    return 1;
                else if (s1[i] < s2[i])
                    return -1;
            }
            return 0;
        }
    }
}